import multiprocessing # Added import for multiprocessing module
from typing import Dict, Callable
from .setting_manager import logger # Corrected import path
import os
import signal
import sys

class ProcessManager:
    def __init__(self):
        self.processes: Dict[str, multiprocessing.Process] = {}
        self._lock = multiprocessing.Lock()
        self.root_pid = os.getppid()  # 获取真正的根进程PID
        self.main_pid = os.getpid()  # 主控制进程PID

    def add_process(self, name: str, target: Callable) -> None:
        """添加新进程并进行参数校验"""
        with self._lock:
            if not isinstance(name, str):
                raise TypeError("进程名称必须是字符串类型")
            if name in self.processes:
                raise ValueError(f"进程 '{name}' 已存在")
            if not callable(target):
                raise TypeError("目标必须是可调用对象")

            self.processes[name] = multiprocessing.Process(target=target, name=name)

    def start_process(self, name: str) -> None:
        """安全启动进程"""
        with self._lock:
            process = self.processes.get(name)
            if not process:
                raise ValueError(f"进程 '{name}' 不存在")

            if process.is_alive():
                raise RuntimeError(f"进程 '{name}' 已在运行")

            process.daemon = False  # 确保非守护进程
            process.start()
            logger.info("[ProcessMgr] 进程 '%s' 启动成功 (PID: %s)", name, process.pid)

    def _safe_terminate(self, process: multiprocessing.Process, name: str) -> None:
        """封装安全的终止逻辑"""
        try:
            if process.is_alive():
                logger.debug("[ProcessMgr] 正在终止进程 '%s' (PID: %s)...", name, process.pid)
                process.terminate()
                process.join(timeout=5)

                if process.is_alive():
                    logger.warning("[ProcessMgr] 强制终止进程 '%s'", name)
                    process.kill()
                    process.join()

                logger.info("[ProcessMgr] 进程 '%s' 已终止", name)
        except Exception as e:
            logger.exception("[ProcessMgr] 终止进程异常: %s", e)

    def terminate_process(self, name: str) -> None:
        """终止指定进程"""
        with self._lock:
            process = self.processes.get(name)
            if not process:
                raise ValueError(f"进程 '{name}' 不存在")
            
            self._safe_terminate(process, name)

    def terminate_all(self) -> None:
        """终止所有进程（包含系统进程处理）"""
        with self._lock:
            # 先终止普通子进程
            for name, process in list(self.processes.items()):
                if not name.startswith("#"):
                    self._safe_terminate(process, name)
            
            # 处理系统级进程
            try:
                # 发送终止信号给主控制进程
                os.kill(self.main_pid, signal.SIGTERM)
                logger.info(f"已发送终止信号到主控制进程 ({self.main_pid})")
            except ProcessLookupError:
                logger.warning("主控制进程已提前退出")

            # 根进程处理（需谨慎操作）
            if sys.platform != "win32":  # Windows不支持
                try:
                    os.killpg(os.getpgid(self.root_pid), signal.SIGTERM)
                except Exception as e:
                    logger.error(f"终止根进程组失败: {e}")

    def _cleanup_processes(self) -> None:
        """清理已完成的进程"""
        dead = [name for name, p in self.processes.items() if not p.is_alive()]
        for name in dead:
            del self.processes[name]

    def list_processes(self) -> None:
        """列出所有进程状态（增强类型检查）"""
        with self._lock:
            logger.info("[ProcessMgr] ====== 进程状态 ======")
            for name, process in self.processes.items():
                # 类型安全检查
                if isinstance(process, multiprocessing.Process):
                    status = "运行中" if process.is_alive() else "已停止"
                    pid_info = process.pid or "N/A"
                else:  # 处理系统虚拟进程
                    status = "系统进程"
                    pid_info = getattr(process, 'pid', 'N/A')
                
                logger.info("- %-20s: %s (PID: %s)", 
                          name, status, pid_info)
            logger.info("=" * 35)

    def add_system_processes(self):
        """添加系统级进程信息"""
        with self._lock:
            # 虚拟进程对象用于记录系统进程
            self.processes["#RootProcess"] = type('', (), {'pid': self.root_pid})()
            self.processes["#MainController"] = type('', (), {'pid': self.main_pid})()

    def print_process_tree(self):
        """打印进程树结构"""
        tree_str = f"""
        System Process Tree
        └─ {self.root_pid} (Root)
           └─ {self.main_pid} (Main Controller)"""
        
        for name, process_obj in self.processes.items():
            if not name.startswith("#") and hasattr(process_obj, 'pid'): # 过滤掉系统进程和没有pid属性的条目
                pid = process_obj.pid if process_obj.pid else 'N/A'
                tree_str += f"\n              ├─ {pid} ({name})"
        
        logger.info(tree_str)
